package com.cherrypt.api.core.util;

import com.cherrypt.api.common.util.RegexUtils;
import com.cherrypt.api.model.dto.DoubanDto;
import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * @author intent
 * @date 2019/8/6 9:58
 * @about <link href='http://zzyitj.xyz/'/>
 */
public class DoubanUtils {
    private static final Logger logger = LoggerFactory.getLogger(DoubanUtils.class);

    private static final String DOUBAN_API_URL = "https://api.douban.com/v2/";
    private static final String DOUBAN_MOVIE_TYPE = "movie";
    private static final String DOUBAN_MUSIC_TYPE = "music";
    private static final String DOUBAN_BOOK_TYPE = "book";
    private static final String DOUBAN_API_KEY = "0df993c66c0c636e29ecbb5344252a4a";
//    http://douban.uieee.com/v2/movie/

    private static WebClient webClient = WebClient.builder()
            .baseUrl(DOUBAN_API_URL)
            .build();


    public static Mono<JsonNode> getDoubanById(long doubanId, String type) {
        return webClient.get()
                .uri("{type}/{id}?apikey={key}", type, doubanId, DOUBAN_API_KEY)
                .retrieve()
                .bodyToMono(JsonNode.class);
    }

    public static Mono<JsonNode> getDoubanMovieById(long doubanId) {
        return getDoubanById(doubanId, DOUBAN_MOVIE_TYPE);
    }

    public static Mono<JsonNode> getDoubanMusicById(long doubanId) {
        return getDoubanById(doubanId, DOUBAN_MUSIC_TYPE);
    }

    public static Mono<JsonNode> getDoubanBookById(long doubanId) {
        return getDoubanById(doubanId, DOUBAN_BOOK_TYPE);
    }

    public static DoubanDto getDouban(JsonNode rootNode) {
        DoubanDto douban = new DoubanDto();
        JsonNode ratingNode = rootNode.get("rating");
        if (ratingNode != null) {
            JsonNode averageNode = ratingNode.get("average");
            if (averageNode != null && StringUtils.isNotBlank(averageNode.asText())) {
                douban.setRatingAverage(Float.valueOf(averageNode.asText()));
            } else {
                douban.setRatingAverage(0F);
            }
            JsonNode numRatersNode = ratingNode.get("numRaters");
            if (numRatersNode != null) {
                douban.setRatingNumRaters(numRatersNode.asInt());
            } else {
                douban.setRatingNumRaters(0);
            }
        }
        // get author
        JsonNode authorNode = rootNode.get("author");
        douban.setAuthor(getNodeNameString(authorNode, "name"));
        // get alt title
        JsonNode altTitleNode = rootNode.get("alt_title");
        if (altTitleNode != null && StringUtils.isNotBlank(altTitleNode.asText())) {
            douban.setAltTitle(altTitleNode.asText());
        }
        // get title
        JsonNode titleNode = rootNode.get("title");
        if (titleNode != null && StringUtils.isNotBlank(titleNode.asText())) {
            douban.setTitle(titleNode.asText());
        }
        // get image
        JsonNode imageNode = rootNode.get("image");
        JsonNode imagesNode = rootNode.get("images");
        if (imageNode != null && StringUtils.isNotBlank(imageNode.asText())) {
            douban.setImage(imageNode.asText());
        } else if (imagesNode != null && StringUtils.isNotBlank(imagesNode.get(0).asText())) {
            douban.setImage(imagesNode.get(0).asText());
        }
        // get summary
        JsonNode summaryNode = rootNode.get("summary");
        if (summaryNode != null && StringUtils.isNotBlank(summaryNode.asText())) {
            douban.setSummary(summaryNode.asText());
        }
        douban.setDoubanId(Long.valueOf(RegexUtils.getMatches("\\d+", rootNode.get("id").asText()).iterator().next()));
        douban.setTags(getNodeNameString(rootNode.get("tags"), "name"));
        // attrs
        JsonNode attrsNode = rootNode.get("attrs");
        // get website
        douban.setWebsite(getArrayNameString(attrsNode, "website"));
        // get language
        douban.setLanguage(getArrayNameString(attrsNode, "language"));
        // get pubdate
        douban.setPubdate(getArrayNameString(attrsNode, "pubdate"));
        // get country
        douban.setCountry(getArrayNameString(attrsNode, "country"));
        // get writer
        douban.setWriter(getArrayNameString(attrsNode, "writer"));
        // get director
        douban.setDirector(getArrayNameString(attrsNode, "director"));
        // get cast
        douban.setCast(getArrayNameString(attrsNode, "cast"));
        douban.setMovieDuration(getArrayNameString(attrsNode, "movie_duration"));
        douban.setMovieType(getArrayNameString(attrsNode, "movie_type"));
        douban.setYear(getArrayNameString(attrsNode, "year"));
        return douban;
    }

    private static String getArrayNameString(JsonNode node, String arrayName) {
        StringBuilder stringBuilder = new StringBuilder();
        if (node != null) {
            JsonNode arrayNode = node.get(arrayName);
            if (arrayNode != null) {
                for (int i = 0; i < arrayNode.size(); i++) {
                    stringBuilder.append(arrayNode.get(i).asText());
                    if (i != arrayNode.size() - 1) {
                        stringBuilder.append(" / ");
                    }
                }
            }
        }
        return stringBuilder.toString();
    }

    private static String getNodeNameString(JsonNode node, String name) {
        StringBuilder stringBuilder = new StringBuilder();
        if (node != null) {
            for (int i = 0; i < node.size(); i++) {
                JsonNode nameNode = node.get(i).get(name);
                if (nameNode != null) {
                    stringBuilder.append(nameNode.asText());
                } else {
                    stringBuilder.append(node.get(i).asText());
                }
                if (i != node.size() - 1) {
                    stringBuilder.append(" / ");
                }
            }
        }
        return stringBuilder.toString();
    }

}
